home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
libs
/
knowhow4
/
ic_part.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1994-10-10
|
6KB
|
210 lines
#include "ic_part.h"
#include <mem.h>
#include "image_p.h"
#include "output.h"
//////////////////////////
void cut_image_horiz(imageP image, int height, int leave_up)
{
if(leave_up)
imageP(image)->ymax = height - 1;
else
{
int line_size = ((imageP(image)->xmax + 1 + 7) >> 3) << N_PLANE_SH;
memcpy(imageP(image)->data,
imageP(image)->data + line_size * height,
(imageP(image)->ymax + 1 - height) * line_size);
imageP(image)->ymax -= height;
}
}
//////////////////////////
void cut_image_vert(imageP image, int width, int leave_left)
{
int line_bytes_old = ((image->xmax + 1 + 7) >> 3);
if(leave_left)
{
int line_bytes_new = (width + 7) >> 3;
image->xmax = width - 1;
int i, s, d;
for(i = s = d = 0; i <= image->ymax; i++)
{
for(int plane = 0; plane < N_PLANES; plane++)
{
for(int j = 0; j < line_bytes_new; j++)
image->data[d++] = image->data[s + j];
s += line_bytes_old;
}
}
}
else
{
int bits_left = image->xmax - width + 1;
int i, s, d;
int line_bytes_new = line_bytes_old - ((width + 7) >> 3);
s = (width + 7) >> 3;
for(i = d = 0; i <= image->ymax; i++)
{
for(int plane = 0; plane < N_PLANES; plane++)
{
for(int j = 0; j < line_bytes_new; j++)
image->data[d++] = image->data[s + j];
s += line_bytes_old;
}
}
image->xmax = bits_left - 1;
}
}
////////////////////////////
inline void image_cut(imageP image, imageP work, int x, int bplin, int sz)
{
unsigned char* dest = work->data;
unsigned char* src = image->data + (x >> 3);
memcpy(dest, src, sz); // for 4 planes
memcpy(dest += sz, src += bplin, sz);
memcpy(dest += sz, src += bplin, sz);
memcpy(dest += sz, src += bplin, sz);
}
////////////////////////////
void cut_image(imageP image, rect src, rect dest)
{
int leave_left = 0;
int leave_up = 0;
int height, width;
if(src.origin.X == dest.origin.X)
{
leave_left = 1;
width = dest.width();
}
else
width = src.width() - dest.width();
if(src.origin.Y == dest.origin.Y)
{
leave_up = 1;
height = dest.height();
}
else
height = src.height() - dest.height();
if(!(src.origin.Y == dest.origin.Y && src.corner.Y == dest.corner.Y))
cut_image_horiz(image, height, leave_up);
if(!(src.origin.X == dest.origin.X && src.corner.X == dest.corner.X))
cut_image_vert(image, width, leave_left);
}
///////////////////////////
void put_image_correct(imageP image, rect src) // src in abs screen coord
{
struct viewporttype viewinfo;
getviewsettings(&viewinfo);
setviewport(0, 0, getmaxx(), getmaxy(), 1);
rect r(viewinfo.left, viewinfo.top, viewinfo.right, viewinfo.bottom);
if(r.contains(src))
{
putimage(src.origin.X, src.origin.Y, image, COPY_PUT);
setviewport(viewinfo.left, viewinfo.top,
viewinfo.right, viewinfo.bottom, 1);
return;
}
if(!r.contains(src.origin) && !r.contains(src.corner) &&
!r.contains(loc(src.origin.X, src.corner.Y)) &&
!r.contains(loc(src.corner.X, src.corner.Y)))
{
setviewport(viewinfo.left, viewinfo.top,
viewinfo.right, viewinfo.bottom, 1);
return;
}
rect dest;
dest.origin.X = r.origin.X > src.origin.X ? r.origin.X : src.origin.X;
dest.origin.Y = r.origin.Y > src.origin.Y ? r.origin.Y : src.origin.Y;
dest.corner.X = r.corner.X < src.corner.X ? r.corner.X : src.corner.X;
dest.corner.Y = r.corner.Y < src.corner.Y ? r.corner.Y : src.corner.Y;
cut_image(image, src, dest);
putimage(dest.origin.X, dest.origin.Y, image, COPY_PUT);
setviewport(viewinfo.left, viewinfo.top,
viewinfo.right, viewinfo.bottom, 1);
}
//////////////////////////
void cut(imageP image, rect src) // src - position of rectangle inside image
{
cut_image(image, rect(0, 0, image->xmax, image->ymax),
rect(src.origin, loc(image->xmax, image->ymax)));
src.corner.X -= src.origin.X;
src.corner.Y -= src.origin.Y + 1;
cut_image(image, rect(0, 0, image->xmax, image->ymax),
rect(0, 0, src.corner.X, src.corner.Y));
}
////////////////////////////
void putimage(int x, int y, imageP image, // for 25x80 cells screen, show
int* cells, imageP work, // only cells, which are listed
int bplin, int mode)
{
if(cells == NULL)
::putimage(x, y, image, mode);
else
{
int i = 0; // Cells counter
rect r_out = textRect(rect(x, 0, x + image->xmax, 0));
int r_out_L = r_out.origin.X;
int r_out_R = r_out.corner.X;
int num = 0; // Number of continuous cells.
int s_left; // First cell in visible raw
int raw = y / pScreenSet->cell_height;
int bytes_per_cell = 1 << (pScreenSet->log2cell_width - 3);
int reserv = -5;
while(cells[i] != -1)
{
int top = cells[i] / 80;
if(raw != top || cells[i] < 0) // Skip this raw
{
i++; continue;
}
int left = cells[i] - top * 80;
if(!num) // Start in raw of cells
s_left = left;
if(left < r_out_R && left >= r_out_L
&& (!num || (cells[i] == reserv + 1)))
{
reserv = cells[i];
if(!((y + 1) % pScreenSet->cell_height))
cells[i] = -2;
num++;
}
else
{
if(num) // end of visible raw
{
int r_left = screenXL(s_left);
int sz = bytes_per_cell * num;
work->xmax = (num << pScreenSet->log2cell_width) - 1;
image_cut(image, work, r_left - x, bplin, sz);
::putimage(r_left, y, work, mode);
num = 0;
i--;
}
}
i++;
}
if(cells[i] == -1 && num)
{
int r_left = screenXL(s_left);
int sz = bytes_per_cell * num;
work->xmax = (num << pScreenSet->log2cell_width) - 1;
image_cut(image, work, r_left - x, bplin, sz);
::putimage(r_left, y, work, mode);
}
}
}